/*
 *  Copyright (c) 2019-2020, Medvish
 *  <p>
 *  Licensed under the GNU Lesser General Public License 3.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *  <p>
 * https://www.gnu.org/licenses/lgpl.html
 *  <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.kw.common.core.exception;

import com.alibaba.csp.sentinel.Tracer;
import com.kw.common.core.util.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Medvish
 * @date 2019/2/1
 * 全局的的异常处理器
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {



	/**
	 * 是否ajax请求
	 * @param request
	 * @return
	 */
	public static boolean isAjax(HttpServletRequest request){
		String xRequestedWith = request.getHeader("X-Requested-With");
		if (xRequestedWith != null && xRequestedWith.equalsIgnoreCase("XMLHttpRequest")) {
			return true;
		}
		return false;
	}
	/**
	 * todo 全局异常 有bug. 暂时这样 如果再有bug就不作用在oauth2 server
	 * 阅读AuthorizationEndpoint源码 无用户会抛出
	 * InsufficientAuthenticationException
	 * 本身即使报出异常  也会跳转页面到登陆
	 * 这时候会被全局拦截 直接输出json  导致无法跳转页面
	 * @param e the e
	 * @return R
	 */
	@ExceptionHandler(Exception.class)
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public R exception(HttpServletRequest request,Exception e) throws Exception {
		Tracer.trace(e);
		if(e instanceof BusinessException){
			R r  = new R();
			return r.setCode(((BusinessException) e).getCode()).setMsg(e.getMessage());
		}
		log.error("全局异常信息 ex={}", e.getMessage(), e);
		return R.failed(e);
	}

	/**
	 * validation Exception
	 *
	 * @param exception
	 * @return R
	 */
	@ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	public R bodyValidExceptionHandler(MethodArgumentNotValidException exception) {
		List<FieldError> fieldErrors = exception.getBindingResult().getFieldErrors();
		log.warn(fieldErrors.stream().map(FieldError::getDefaultMessage).collect(Collectors.joining(",")));
		return R.failed(fieldErrors.stream().map(FieldError::getDefaultMessage).collect(Collectors.joining(",")));

	}

}
